#include "errno.h"
#include "stdio.h"
#include "stdlib.h"
#include "linux/module.h"
#include "los_vm_map.h"
#include "los_vm_lock.h"
#include "los_arch_mmu.h"
#include "fs/fs.h"
#include <sys/bus.h>
#include "fb.h"

static unsigned char fake_gram[64]; //use for trick nuttx's fb initial


static int getvideoinfo(struct fb_vtable_s *vtable, struct fb_videoinfo_s *vinfo)
{
	vinfo->nplanes = 1;
	return 0;
}

static int getplaneinfo(struct fb_vtable_s *vtable, int planeno, struct fb_planeinfo_s *pinfo)
{
	pinfo->fbmem = fake_gram;
	pinfo->fblen = 64;
	pinfo->bpp = 24;
	return 0;
}

static int getoverlayinfo(struct fb_vtable_s *vtable, int overlayno,  struct fb_overlayinfo_s *oinfo)
{
	oinfo->fbmem = fake_gram;
	oinfo->fblen = 64;	
	return 0;
}

static int fb_open(struct fb_vtable_s *vtable)
{
	return 0;
}

static int fb_release(struct fb_vtable_s *vtable)
{
	return 0;
}

static int fb_ioctl(struct fb_vtable_s *vtable, int cmd, unsigned long arg)
{
	return 0;
}

static ssize_t fb_mmap(struct fb_vtable_s *vtable, LosVmMapRegion *region)
{
	VADDR_T vaddr = region->range.base;
	LosVmSpace *space = LOS_SpaceGet(vaddr);
	size_t size;
	uint32_t flag;
		
    size = DISPLAY_GRAM_SIZE;
    // if (size == 0 || (size & ~PAGE_MASK) || size > DISPLAY_GRAM_SIZE || region->pgOff != 0) 
	// {
    //     return -EINVAL;
    // }

    flag = region->regionFlags;
    flag &= (~VM_MAP_REGION_FLAG_CACHED);
    flag |= VM_MAP_REGION_FLAG_UNCACHED;

    if (LOS_ArchMmuMap(&space->archMmu, vaddr, DISPLAY_GRAM_ADDR, size >> PAGE_SHIFT, flag) <= 0)
	{
        return -EAGAIN;
    }

    return 0;
}


static struct fb_vtable_s g_fbinterface =
{
	.getvideoinfo = getvideoinfo,
	.getplaneinfo = getplaneinfo,
	.getoverlayinfo = getoverlayinfo,
	.fb_open = fb_open,
	.fb_release = fb_release,
	.fb_ioctl = fb_ioctl,
	.fb_mmap = fb_mmap,
};

struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
{
	return &g_fbinterface;
}

int up_fbinitialize(int display)
{
	return 0;
}

int sunxifb_init(void)
{
	return fb_register(0, 0);	
}

module_init(sunxifb_init);
